package org.dingyom.gift.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import org.apache.logging.log4j.util.Strings;
import org.dingyom.gift.clients.LoginUserClient;
import org.dingyom.gift.domain.Employee;
import org.dingyom.gift.domain.LoginUser;
import org.dingyom.gift.domain.Tenant;
import org.dingyom.gift.dto.TenantEnterDto;
import org.dingyom.gift.exception.BusinessException;
import org.dingyom.gift.exception.asserts.Assert;
import org.dingyom.gift.exception.code.StatusCode;
import org.dingyom.gift.mapper.EmployeeMapper;
import org.dingyom.gift.mapper.TenantMapper;
import org.dingyom.gift.query.TenantQuery;
import org.dingyom.gift.service.ITenantService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.dingyom.gift.util.AjaxResult;
import org.dingyom.gift.util.PageList;
import org.dingyom.gift.util.encrypt.MD5;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author dingyom
 * @since 2022-10-09
 */
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private LoginUserClient loginUserClient;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Override
    public PageList<Tenant> selectPageList(TenantQuery query) {
        //分页不需要自己写 它自己有封装，只需要传入分页条件
        Page<Object> page = new Page<>(query.getPage(), query.getRows());
        //做跨表查询
        List<Tenant> datas = tenantMapper.loadPageList(page,query);

        return new PageList<>(page.getTotal(),datas);
    }

    @Override
    @Transactional
    public AjaxResult tenantEnter(TenantEnterDto dto) {
        //租户入驻 TODO
        Employee admin = dto.getAdmin();//管理员
        Tenant tenant = dto.getTenant();//租户信息
        Long mealId = dto.getMealId();//套餐id

        //null校验
        nullVerify(dto);
        //盐值
        String uuid = UUID.randomUUID().toString();
        String salt = "dingyom"+uuid;
        //MD5加密
        String passForMD5 = MD5.getMD5(admin.getPassword()+salt);
        //保存loginUser
        LoginUser loginUser = new LoginUser();
        loginUser.setUsername(admin.getUsername());
        loginUser.setPassword(passForMD5);
        loginUser.setEmail(admin.getEmail());
        loginUser.setTel(admin.getTel());
        loginUser.setType(1);//1表示管理人员 0表示用户
        loginUser.setSalt(salt);
        AjaxResult ajaxResult = loginUserClient.saveUser(loginUser);
        Object obj = ajaxResult.getResultObj();
        //这里有个坑，Long存放进一个Object的内存中 比如AjaxResult 和map<Sstring,Object>中 再拿出来会降级成为Integer
        Integer loginInteger = (Integer)obj;
        Long loginId = loginInteger.longValue();
        //获取loginUser的id 存入admin的loginId
        admin.setLoginId(loginId);
        admin.setInputTime(new Date());
        admin.setState(0);

        admin.setPassword(passForMD5);
        //保存管理员信息 返回管理员id
        employeeMapper.insert(admin);
        Long adminId = admin.getId();
        tenant.setRegisterTime(new Date());
        tenant.setState(0);
        tenant.setAdminId(adminId);

        tenantMapper.insert(tenant);

        //保存租户和套餐关联表
        Long tenantId = tenant.getId();
        Map<String,Object> map = new HashMap<>();
        //设置过期时间 当前时间加1年
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        instance.add(Calendar.YEAR, 1);
        Date expireDate = instance.getTime();//过期时间

        map.put("tenantId", tenantId);
        map.put("mealId",mealId);
        map.put("expireDate", expireDate);
        map.put("state",0);//状态,是否过期 0 未支付，1已经购买，2过期
        tenantMapper.insertMeal(map);
        return AjaxResult.me();
    }

    //空校验 初始版-没有自定义异常处理
    /*private void nullVerify(TenantEnterDto dto) {
        Tenant tenant = dto.getTenant();
        Employee admin = dto.getAdmin();
        if (dto == null) {
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        if (Strings.isEmpty(tenant.getCompanyName())) {//租户名
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        if (admin == null) {//管理员
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        //两次密码比对
        if (admin.getComfirmPassword() == null|| admin.getPassword()==null
                || !dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())) {
            throw new RuntimeException("系统错误！请输入相关信息后再操作");
        }
        //租户是否存在
        EntityWrapper<Tenant> warpper = new EntityWrapper<>();
        warpper.eq("company_name", tenant.getCompanyName());
        List<Tenant> tenants = tenantMapper.selectList(warpper);
        if (tenants != null||tenants.size()>0) {
            throw new RuntimeException("系统错误！该已经租户存在");
        }
    }*/

    //自定义异常处理
    /*private void nullVerify(TenantEnterDto dto) {
        Tenant tenant = dto.getTenant();
        Employee admin = dto.getAdmin();
        if (dto == null) {
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        }
        if (Strings.isEmpty(tenant.getCompanyName())) {//租户名
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        }
        if (admin == null) {//管理员
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        }
        //两次密码比对
        if (admin.getComfirmPassword() == null|| admin.getPassword()==null
                || !dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())) {
            throw new BusinessException("系统错误！请输入相关信息后再操作");
        }
        //租户是否存在
        EntityWrapper<Tenant> warpper = new EntityWrapper<>();
        warpper.eq("company_name", tenant.getCompanyName());
        List<Tenant> tenants = tenantMapper.selectList(warpper);
        if (tenants != null||tenants.size()>0) {
            throw new BusinessException("系统错误！该已经租户存在");
        }
    }*/

    //断言
    /*private void nullVerify(TenantEnterDto dto) {
        Tenant tenant = dto.getTenant();
        Employee admin = dto.getAdmin();
        Assert.notNull(dto, "系统错误！请输入相关信息后操作");
        Assert.isNotEmpty(tenant.getCompanyName(),"系统错误！请输入相关信息后再操作");
        Assert.notNull(admin,"系统错误！请输入相关信息后再操作");
        //两次密码判空
        Assert.isNotEmpty(admin.getComfirmPassword(),"系统错误！请输入相关信息后再操作");
        Assert.isNotEmpty(admin.getPassword(),"系统错误！请输入相关信息后再操作");
        //两次密码比对
        if (!dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())) {
            throw new BusinessException("密码校验失败！请重新输入");
        }
        //租户是否存在
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>()
                .eq("company_name", tenant.getCompanyName()));
        Assert.listIsNull(tenants, "系统错误！该租户已经存在");

        //管理员是否存在
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>()
                .eq("username", admin.getUsername()));
        Assert.listIsNull(employees,"系统错误！该管理员已经存在");
    }*/

    //jsr303 版
    /*private void nullVerify(TenantEnterDto dto) {
        Tenant tenant = dto.getTenant();
        Employee admin = dto.getAdmin();
        //两次密码比对
        if (!dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())) {
            throw new BusinessException("密码校验失败！请重新输入");
        }
        //租户是否存在
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>()
                .eq("company_name", tenant.getCompanyName()));
        Assert.listIsNull(tenants, "系统错误！该租户已经存在");

        //管理员是否存在
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>()
                .eq("username", admin.getUsername()));
        Assert.listIsNull(employees,"系统错误！该管理员已经存在");
    }*/

    //jsr303+错误码
    private void nullVerify(TenantEnterDto dto) {
        Tenant tenant = dto.getTenant();
        Employee admin = dto.getAdmin();
        //两次密码比对
        if (!dto.getAdmin().getPassword().equals(dto.getAdmin().getComfirmPassword())) {
            throw new BusinessException("密码校验失败！请重新输入");
        }
        //租户是否存在
        List<Tenant> tenants = tenantMapper.selectList(new EntityWrapper<Tenant>()
                .eq("company_name", tenant.getCompanyName()));

        Assert.listIsNull(tenants, StatusCode.CODE_400_TENANT_EXSIT);

        //管理员是否存在
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>()
                .eq("username", admin.getUsername()));
        Assert.listIsNull(employees,StatusCode.CODE_400_TENANT_ADMIN_EXSIT);
    }
}
